// MAYANK VERMA
// Roll No. 2010048
// LINKED LIST IMPLEMENTATION

#include<stdio.h>
#include<stdlib.h>

struct node
{
 int value;
 struct node *next;
} *first = NULL, *cur = NULL, *last=NULL;





// 1. Append
void append(int num)
{
 struct node *tempo, *temp;
 temp=first;
 tempo = malloc(sizeof(struct node));
 tempo->value = num;
 tempo->next = NULL;
 while(temp->next!=NULL)
  {
   temp=temp->next;
  }
 if (first == NULL)
   first=tempo;  
 else
  temp->next=tempo; 
}


// 2. Sort
void sort(struct node *temp)
{
 struct node *tempo;
 tempo=temp;
 int x, changer;
 while(tempo!=NULL)
 {
  x=min(tempo);
  changer=x;
  x=tempo->value;
  tempo->value=changer;
 }
 displaying(temp);

}

// 3. Reverse
void reverse(struct node *temp)
{
 struct node *first, *second, *last;
int i=0;

 first=last=temp;

 second=first->next;
 while (last!=NULL)
  {i++;   
   last=last->next;
  }
for (int a=0;a<i;a++)
{
first=first->next;
second=second->next;
if(second==last){

second->next=first;
last=first;
}

}
i--; 

}


// 4. Index(x) : First Occurence of x
void indexing(struct node *temp, int x)
{
  struct node *tempo;
  tempo=temp;
  int inn=0;
  while(tempo!=NULL)
  {
   if (tempo->value==x)
    {
     printf("\nValue %3d occurs at index: %2d\n", x, inn);
     break;
    }
   else 
    {
     inn++;
     tempo=tempo->next;
    }
  }
}

// 5. Insert(i, x): Insert x into list at index i
void insert(struct node *temp, int i, int x)
{
  struct node *tempo, *allocate, *prev;
  int j=0;
  tempo=temp;
  allocate = malloc(sizeof(struct node));
  allocate->value = x;
  while(j<i)
  {
   prev=tempo;
   tempo=tempo->next;
   j++;
  }
  prev->next=allocate;
  allocate->next=tempo;

}


// 6. Count(x): Number of occurences of x in list
void count(struct node *temp, int x)
{
 struct node *tempo;
 tempo=temp;
 int countt=0;
 while(tempo->next!=NULL)
  {
   if (tempo->value==x)
    countt++;
  }
  printf("\n\n Number %3d occurs %3d times in the list\n", x, countt);
 
}

// 7. Remove(x): delete first occurence of x
void removing(struct node *temp, int x)
{ struct node *tempo, *prev;
  prev=tempo=temp;
  int j=0;
  while(tempo->next!=NULL)
   {
	if (tempo->value==x)
	{
	 if(j==0)
	  {
		prev=prev->next;
		break;
	  }
	 else
	  {
	   prev->next=tempo->next;
	   free(tempo);
	   break;	
	  }
	}
        else
        { if (j>=1)
            {
	     prev=prev->next;
	    }
	  j++;
	  tempo=tempo->next;
	}
   }

}


// 8. int pop(i): Delete ith element and return it's value
int pop(struct node *temp, int i)
{   struct node *tempo, *prev;
    prev=tempo=temp;
    int val, j=0, flag=0;
    while(tempo->next!=NULL)
    {
     if (j==i)
	flag=1;
     else
        { if (j>=1)
             prev=prev->next;
	  j++;
	  tempo=tempo->next;
	}
    }
    if (flag==1)
     {  val=tempo->value;
	prev->next=tempo->next;
	free(tempo);
        return val;
     }
    
}

// 9. in_list(x): Check if x is in list
void in_list(struct node *temp, int check)
{ int flag=0;
 while (temp->next!=NULL)
  {
   if(check==temp->value)
    { flag=1;
      break;  
    }
   temp=temp->next;
  }
 if (flag==1)
  printf("\n\nElement is in the list\n");
 else
  printf("\n\nElement is NOT in the list\n");
}



// 10. DISPLAY
void displaying(struct node *temp)
{
 struct node *tempo;
 tempo=temp;
 while (tempo->next!=NULL)
  {
   printf(" %3d ", tempo->value);
  }
 
}


// 11. MIN
int min(struct node *temp)
{
 int mini;
 if (temp->next!=NULL)
  mini=temp->value;
 while (temp->next!=NULL)
  {
   if (mini>temp->value)
    {
	mini=temp->value;
	
    }
   temp=temp->next;
  }
 return mini;
}
// 12. MAX
int max(struct node *temp)
{
 int maxi;
 if (temp->next!=NULL)
  maxi=temp->value;
 while (temp->next!=NULL)
  {
   if (maxi<temp->value)
    {
	maxi=temp->value;
	
    }
   temp=temp->next;
  }
 return maxi;
}


//MAIN FUNCTION
void main()
{ int choice, n, maxx, minn, element;
  char ch='y';
  printf("\n\n\t\tLIST IMPLEMENTATION THROUGH LINKED LIST");
  do 
  {

   printf("\n\n \n\t\t 1. APPEND"); 
   printf("\n\t\t 2. SORT"); 
   printf("\n\t\t 3. REVERSE "); 
   printf("\n\t\t 4. INDEX "); 
   printf("\n\t\t 5. INSERT "); 
   printf("\n\t\t 6. COUNT "); 
   printf("\n\t\t 7. REMOVE "); 
   printf("\n\t\t 8. POP "); 
   printf("\n\t\t 9. IN LIST? "); 
   printf("\n\t\t 10. DISPLAY "); 
   printf("\n\t\t 11. MIN VALUE"); 
   printf("\n\t\t 12. MAX VALUE "); 
   printf("\n\n\t\t Enter Your Choice: \n\n");
   scanf("%d", &choice);
   switch(choice)
	{
	 case 1: {
		  printf("\n Enter the element to be appended: ");
		  scanf("%d", &n);
 		  append(n);
		  break;
		 }

	 case 2: { 
	          sort(first);
		  break;
		 }

	 case 3: {
		  break;
		 }

	 case 4: {
	 	  printf("\n Enter the element whose index has to be found: ");
		  scanf("%d", &n);
 		  indexing(first, n);	 	  
		  break;
		 }

	 case 5: {
	          printf("\n Enter the ELEMENT to be inserted: ");
		  scanf("%d", &element);
	          printf("\n Enter the INDEX at which element should be inserted: ");
		  scanf("%d", &n);		  
 		  insert(first, n, element);
		  break;
		 }

	 case 6: {
	          printf("\n Enter the element to be counted: ");
		  scanf("%d", &element);
		  count(first, element);
		  break;
		 }

	 case 7: {
	          printf("\n Enter the element to be removed: ");
		  scanf("%d", &element);
		  removing(first, element);
		  break;
		 }

	 case 8: {
		  printf("\n Enter the index of element to be popped: ");
		  scanf("%d", &n);
		  element=pop(first, n);
		  printf("\n Enter Popped Element is: %3d ", element);
		  break;
		 }

	 case 9: {
		  printf("\n Enter the element to be checked for: ");
		  scanf("%d", &n);
		  in_list(first, n);
		  break;
		 }

	 case 10:{ 
		  displaying(first);
		  break;
		 }
	 case 11:{ 
		  minn=min(first);
       		  printf("\n\nThe Minimum Value in the LIST is: %3d \n", minn);		  
		  break;
		 }
	 case 12:{
		  maxx=max(first);
       		  printf("\n\nThe Maximum Value in the LIST is: %3d \n", maxx);		  
		  break;
		 }
	 default: { printf("\n\nERROR: INVALID CHOICE !!\n");
		  break;
		 }
		 

	};        // switch ends

	
   printf("\n\n\t\tDO you want to continue?\n");
   scanf("%s", &ch);	
  }while(ch=='Y' || 'y');


  
  
}             // main ends






